{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Cross-Framework LLM Tool Integration with AG2\n",
    "\n",
    "In this tutorial, we demonstrate how to integrate LLM tools from various frameworks—including [LangChain Tools](https://python.langchain.com/v0.1/docs/modules/tools), [CrewAI Tools](https://github.com/crewAIInc/crewAI-tools/tree/main), and [PydanticAI Tools](https://ai.pydantic.dev/tools/) into the AG2 framework. This process enables smooth interoperability between these systems, allowing developers to leverage the unique capabilities of each toolset within AG2's flexible agent-based architecture. By the end of this guide, you will understand how to configure agents, adapt these tools for use in AG2, and validate the integration through practical examples."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## LangChain Tools Integration\n",
    "\n",
    "LangChain is a popular framework that offers a wide range of tools to work with LLMs. LangChain has already implemented a variety of tools that can be easily integrated into AG2. You can explore the available tools in the [LangChain Community Tools](https://github.com/langchain-ai/langchain-community/tree/main/libs/community/langchain_community/tools) folder. These tools, such as those for querying APIs, web scraping, and text generation, can be quickly incorporated into AG2, providing powerful functionality for your agents.\n",
    "\n",
    "### Installation\n",
    "To integrate LangChain tools into the AG2 framework, install the required dependencies:\n",
    "\n",
    "```bash\n",
    "pip install -U ag2[openai,interop-langchain]\n",
    "```\n",
    "\n",
    "> **Note:** If you have been using `autogen` or `ag2`, all you need to do is upgrade it using:  \n",
    "> ```bash\n",
    "> pip install -U autogen[openai,interop-langchain]\n",
    "> ```\n",
    "> or  \n",
    "> ```bash\n",
    "> pip install -U ag2[openai,interop-langchain]\n",
    "> ```\n",
    "> as `autogen`, and `ag2` are aliases for the same PyPI package.  \n",
    "\n",
    "\n",
    "Additionally, this notebook uses LangChain's [Wikipedia Tool](https://api.python.langchain.com/en/latest/tools/langchain_community.tools.wikipedia.tool.WikipediaQueryRun.html), which requires the `wikipedia` package. Install it with:\n",
    "\n",
    "```bash\n",
    "pip install wikipedia\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Imports\n",
    "\n",
    "Import necessary modules and tools.\n",
    "\n",
    "- [WikipediaQueryRun](https://api.python.langchain.com/en/latest/tools/langchain_community.tools.wikipedia.tool.WikipediaQueryRun.html) and [WikipediaAPIWrapper](https://python.langchain.com/api_reference/community/utilities/langchain_community.utilities.wikipedia.WikipediaAPIWrapper.html): Tools for querying Wikipedia.\n",
    "- `AssistantAgent` and `UserProxyAgent`: Agents that facilitate communication in the AG2 framework.\n",
    "- `Interoperability`: This module acts as a bridge, making it easier to integrate LangChain tools with AG2’s architecture."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "from langchain_community.tools import WikipediaQueryRun\n",
    "from langchain_community.utilities import WikipediaAPIWrapper\n",
    "\n",
    "from autogen import AssistantAgent, UserProxyAgent\n",
    "from autogen.interop import Interoperability"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Agent Configuration\n",
    "\n",
    "Configure the agents for the interaction.\n",
    "\n",
    "- `config_list` defines the LLM configurations, including the model and API key.\n",
    "- `UserProxyAgent` simulates user inputs without requiring actual human interaction (set to `NEVER`).\n",
    "- `AssistantAgent` represents the AI agent, configured with the LLM settings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "config_list = [{\"model\": \"gpt-5\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]\n",
    "user_proxy = UserProxyAgent(\n",
    "    name=\"User\",\n",
    "    human_input_mode=\"NEVER\",\n",
    ")\n",
    "\n",
    "chatbot = AssistantAgent(\n",
    "    name=\"chatbot\",\n",
    "    llm_config={\"config_list\": config_list},\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tool Integration\n",
    "\n",
    "- Initialize and register the LangChain tool with AG2.\n",
    "- [WikipediaAPIWrapper](https://python.langchain.com/api_reference/community/utilities/langchain_community.utilities.wikipedia.WikipediaAPIWrapper.html): Configured to fetch the top 1 result from Wikipedia with a maximum of 1000 characters per document.\n",
    "- [WikipediaQueryRun](https://api.python.langchain.com/en/latest/tools/langchain_community.tools.wikipedia.tool.WikipediaQueryRun.html): A LangChain tool that executes Wikipedia queries.\n",
    "- `Interoperability`: Converts the LangChain tool into a format compatible with the AG2 framework.\n",
    "- `ag2_tool.register_for_execution(user_proxy)`: Registers the tool for use by the user_proxy agent.\n",
    "- `ag2_tool.register_for_llm(chatbot)`: Registers the tool for integration with the chatbot agent.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "api_wrapper = WikipediaAPIWrapper(top_k_results=1, doc_content_chars_max=1000)\n",
    "langchain_tool = WikipediaQueryRun(api_wrapper=api_wrapper)\n",
    "\n",
    "interop = Interoperability()\n",
    "ag2_tool = interop.convert_tool(tool=langchain_tool, type=\"langchain\")\n",
    "\n",
    "ag2_tool.register_for_execution(user_proxy)\n",
    "ag2_tool.register_for_llm(chatbot)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "message = \"Tell me about the history of the United States\"\n",
    "user_proxy.initiate_chat(recipient=chatbot, message=message, max_turns=2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CrewAI Tools Integration\n",
    "\n",
    "CrewAI provides a variety of powerful tools designed for tasks such as web scraping, search, code interpretation, and more. These tools are easy to integrate into the AG2 framework, allowing you to enhance your agents with advanced capabilities. You can explore the full list of available tools in the [CrewAI Tools](https://github.com/crewAIInc/crewAI-tools/tree/main) repository.\n",
    "\n",
    "### Installation\n",
    "Install the required packages for integrating CrewAI tools into the AG2 framework.\n",
    "This ensures all dependencies for both frameworks are installed.\n",
    "\n",
    "```bash\n",
    "pip install -U ag2[openai,interop-crewai]\n",
    "```\n",
    "\n",
    "> **Note:** If you have been using `autogen` or `ag2`, all you need to do is upgrade it using:  \n",
    "> ```bash\n",
    "> pip install -U autogen[openai,interop-crewai]\n",
    "> ```\n",
    "> or  \n",
    "> ```bash\n",
    "> pip install -U ag2[openai,interop-crewai]\n",
    "> ```\n",
    "> as `autogen`, and `ag2` are aliases for the same PyPI package.  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Imports\n",
    "\n",
    "Import necessary modules and tools.\n",
    "\n",
    "- [ScrapeWebsiteTool](https://docs.crewai.com/tools/scrapewebsitetool) are the CrewAI tools for web scraping\n",
    "- `AssistantAgent` and `UserProxyAgent` are core AG2 classes.\n",
    "- `Interoperability`: This module acts as a bridge, making it easier to integrate CrewAI tools with AG2’s architecture."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "from crewai_tools import ScrapeWebsiteTool\n",
    "\n",
    "from autogen import AssistantAgent, UserProxyAgent\n",
    "from autogen.interop import Interoperability"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Agent Configuration\n",
    "\n",
    "Configure the agents for the interaction.\n",
    "\n",
    "- `config_list` defines the LLM configurations, including the model and API key.\n",
    "- `UserProxyAgent` simulates user inputs without requiring actual human interaction (set to `NEVER`).\n",
    "- `AssistantAgent` represents the AI agent, configured with the LLM settings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "config_list = [{\"model\": \"gpt-5\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]\n",
    "user_proxy = UserProxyAgent(\n",
    "    name=\"User\",\n",
    "    human_input_mode=\"NEVER\",\n",
    ")\n",
    "\n",
    "chatbot = AssistantAgent(\n",
    "    name=\"chatbot\",\n",
    "    llm_config={\"config_list\": config_list},\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tool Integration\n",
    "\n",
    "Initialize and register the CrewAI tool with AG2.\n",
    "\n",
    "- `crewai_tool` is an instance of the [ScrapeWebsiteTool](https://docs.crewai.com/tools/scrapewebsitetool) from CrewAI.\n",
    "- `Interoperability` converts the CrewAI tool to make it usable in AG2.\n",
    "- `register_for_execution` and `register_for_llm` allow the tool to work with the UserProxyAgent and AssistantAgent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "interop = Interoperability()\n",
    "crewai_tool = ScrapeWebsiteTool()\n",
    "ag2_tool = interop.convert_tool(tool=crewai_tool, type=\"crewai\")\n",
    "\n",
    "ag2_tool.register_for_execution(user_proxy)\n",
    "ag2_tool.register_for_llm(chatbot)\n",
    "\n",
    "message = \"Scrape the website https://ag2.ai/\"\n",
    "\n",
    "chat_result = user_proxy.initiate_chat(recipient=chatbot, message=message, max_turns=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(chat_result.summary)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PydanticAI Tools Integration\n",
    "\n",
    "[PydanticAI](https://ai.pydantic.dev/) is a newer framework that offers powerful capabilities for working with LLMs. Although it currently does not have a repository with pre-built tools, it provides features like **dependency injection**, allowing you to inject a \"Context\" into a tool for better execution without relying on LLMs. This context can be used for passing parameters or managing state during the execution of a tool. While the framework is still growing, you can integrate its tools into AG2 to enhance agent capabilities, especially for tasks that involve structured data and context-driven logic.\n",
    "\n",
    "### Installation\n",
    "To integrate LangChain tools into the AG2 framework, install the required dependencies:\n",
    "\n",
    "```bash\n",
    "pip install -U ag2[openai,interop-pydantic-ai]\n",
    "```\n",
    "\n",
    "> **Note:** If you have been using `autogen` or `ag2`, all you need to do is upgrade it using:  \n",
    "> ```bash\n",
    "> pip install -U autogen[openai,interop-pydantic-ai]\n",
    "> ```\n",
    "> or  \n",
    "> ```bash\n",
    "> pip install -U ag2[openai,interop-pydantic-ai]\n",
    "> ```\n",
    "> as `autogen`, and `ag2` are aliases for the same PyPI package.  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Imports\n",
    "\n",
    "Import necessary modules and tools.\n",
    "\n",
    "- [BaseModel](https://docs.pydantic.dev/latest/api/base_model/): Used to define data structures for tool inputs and outputs.\n",
    "- [RunContext](https://ai.pydantic.dev/api/tools/#pydantic_ai.tools.RunContext): Provides context during the execution of tools.\n",
    "- [PydanticAITool](https://ai.pydantic.dev/api/tools/#pydantic_ai.tools.Tool): Represents a tool in the PydanticAI framework.\n",
    "- `AssistantAgent` and `UserProxyAgent`: Agents that facilitate communication in the AG2 framework.\n",
    "- `Interoperability`: This module acts as a bridge, making it easier to integrate PydanticAI tools with AG2’s architecture."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "\n",
    "from pydantic import BaseModel\n",
    "from pydantic_ai import RunContext\n",
    "from pydantic_ai.tools import Tool as PydanticAITool\n",
    "\n",
    "from autogen import AssistantAgent, UserProxyAgent\n",
    "from autogen.interop import Interoperability"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Agent Configuration\n",
    "\n",
    "Configure the agents for the interaction.\n",
    "\n",
    "- `config_list` defines the LLM configurations, including the model and API key.\n",
    "- `UserProxyAgent` simulates user inputs without requiring actual human interaction (set to `NEVER`).\n",
    "- `AssistantAgent` represents the AI agent, configured with the LLM settings."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "config_list = [{\"model\": \"gpt-5\", \"api_key\": os.environ[\"OPENAI_API_KEY\"]}]\n",
    "user_proxy = UserProxyAgent(\n",
    "    name=\"User\",\n",
    "    human_input_mode=\"NEVER\",\n",
    ")\n",
    "\n",
    "chatbot = AssistantAgent(\n",
    "    name=\"chatbot\",\n",
    "    llm_config={\"config_list\": config_list},\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Tool Integration\n",
    "\n",
    "Integrate the PydanticAI tool with AG2.\n",
    "\n",
    "- Define a `Player` model using [BaseModel](https://docs.pydantic.dev/latest/api/base_model/) to structure the input data.\n",
    "- Use [RunContext](https://ai.pydantic.dev/api/tools/#pydantic_ai.tools.RunContext) to securely inject dependencies (like the `Player` instance) into the tool function without exposing them to the LLM.\n",
    "- Implement `get_player` to define the tool's functionality, accessing `ctx.deps` for injected data.\n",
    "- Convert the tool to an AG2-compatible format with `Interoperability` and register it for execution and LLM communication.\n",
    "- Convert the PydanticAI tool into an AG2-compatible format using `convert_tool`.\n",
    "- Register the tool for both execution and communication with the LLM by associating it with the `user_proxy` and `chatbot`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Player(BaseModel):\n",
    "    name: str\n",
    "    age: int\n",
    "\n",
    "\n",
    "def get_player(ctx: RunContext[Player], additional_info: str | None = None) -> str:  # type: ignore[valid-type]\n",
    "    \"\"\"Get the player's name.\n",
    "\n",
    "    Args:\n",
    "        ctx: Run context\n",
    "        additional_info: Additional information which can be used.\n",
    "    \"\"\"\n",
    "    return f\"Name: {ctx.deps.name}, Age: {ctx.deps.age}, Additional info: {additional_info}\"  # type: ignore[attr-defined]\n",
    "\n",
    "\n",
    "interop = Interoperability()\n",
    "pydantic_ai_tool = PydanticAITool(get_player, takes_ctx=True)\n",
    "\n",
    "# player will be injected as a dependency\n",
    "player = Player(name=\"Luka\", age=25)\n",
    "ag2_tool = interop.convert_tool(tool=pydantic_ai_tool, type=\"pydanticai\", deps=player)\n",
    "\n",
    "ag2_tool.register_for_execution(user_proxy)\n",
    "ag2_tool.register_for_llm(chatbot)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Initiate a conversation between the `UserProxyAgent` and the `AssistantAgent`.\n",
    "\n",
    "- Use the `initiate_chat` method to send a message from the `user_proxy` to the `chatbot`.\n",
    "- In this example, the user requests the chatbot to retrieve player information, providing \"goal keeper\" as additional context.\n",
    "- The `Player` instance is securely injected into the tool using [RunContext](https://ai.pydantic.dev/api/tools/#pydantic_ai.tools.RunContext), ensuring the chatbot can retrieve and use this data during the interaction."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "user_proxy.initiate_chat(\n",
    "    recipient=chatbot, message=\"Get player, for additional information use 'goal keeper'\", max_turns=3\n",
    ")"
   ]
  }
 ],
 "metadata": {
  "front_matter": {
   "description": "Cross-Framework LLM Tool Integration with AG2",
   "tags": [
    "tools",
    "langchain",
    "crewai",
    "pydanticai"
   ]
  },
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.16"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
